/*
 * Bitmap2D.c
 *
 *  Created on: 29.04.2011
 *      Author: Tavin
 */
#include <stdint.h>
#include "board.h"

#include "Bitmap2D.h"
#include "Display2D.h"
#include "Font_5x5.h"
#include "Font_8x8.h"

/****************************************************************************************/
/*																						*/
/*	Function : Bitmap2D_fill								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.4.29			Status : working   			*/
/*																						*/
/****************************************************************************************/

void Bitmap2D_fill(uint16_t * addres,uint16_t color,uint16_t size)
{
	uint16_t  counter;

	for (counter=0;counter<size;counter++)
		{
		*addres++=color;
		}

}
/****************************************************************************************/
/*																						*/
/*	Function : Bitmap2D_setPixel							Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.4.29			Status : working   			*/
/*																						*/
/****************************************************************************************/

void Bitmap2D_setPixel(Pixel2D_t pixel,uint16_t * addres,uint16_t color)
{

	uint16_t position;

	if ((pixel.position.x>=pixel.displaySize.x) ||
			(pixel.position.y>=pixel.displaySize.y))
		return;

	position=pixel.position.x+(pixel.position.y*(pixel.displaySize.x));

	addres+=position;
	*addres=color;

}

/****************************************************************************************/
/*																						*/
/*	Function : Bitmap2D_getPixel							Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.5.16			Status : working   			*/
/*																						*/
/****************************************************************************************/

uint16_t Bitmap2D_getPixel(Pixel2D_t pixel,uint16_t * addres)
{
	uint16_t color;
	uint16_t position;

	if ((pixel.position.x>=pixel.displaySize.x) ||
			(pixel.position.y>=pixel.displaySize.y))
		return (0);

	position=pixel.position.x+(pixel.position.y*(pixel.displaySize.x));

	addres+=position;
	color=*addres;

	return(color);
}





void Bitmap2D_drawLine(int8_t x,int8_t y,int8_t dx,int8_t dy,uint16_t * addres,Dimension2D_t *size,uint16_t color )
{
	int counter;
	Pixel2D_t pixel;


	int8_t xa;
	int8_t ya;


	if (dx<0)
		{
		xa=-dx;
		}
	else
		{
		xa=dx;
		}

	if (dy<0)
		{
		ya=-dy;
		}
	else
		{
		ya=dy;
		}

	pixel.displaySize.x=size->x;
	pixel.displaySize.y=size->y;

	pixel.position.x=x;
	pixel.position.y=y;

	Bitmap2D_setPixel(pixel,addres,color);




	if (xa>ya)
		{

		if (dx>=0)
			{
			for (counter=1;counter<=xa;counter++)
				{
				pixel.position.x++;
				pixel.position.y=y+(dy*(counter)/xa);
					Bitmap2D_setPixel(pixel,addres,color);
				}
			}

			else
			{
				for (counter=1;counter<=xa;counter++)
					{
					pixel.position.x--;
					pixel.position.y=y+(dy*(counter)/xa);
						Bitmap2D_setPixel(pixel,addres,color);
					}
			}
		}

		else
			{
			if (dy>=0)
				{
				for (counter=1;counter<=ya;counter++)
					{
					pixel.position.y++;
					pixel.position.x=x+(dx*(counter)/ya);
					Bitmap2D_setPixel(pixel,addres,color);
					}
				}

				else
				{
				for (counter=1;counter<=ya;counter++)
					{
					pixel.position.y--;
					pixel.position.x=x+(dx*(counter)/ya);
					Bitmap2D_setPixel(pixel,addres,color);
					}
				}


			}




}


/****************************************************************************************/
/*																						*/
/*	Function : Bitmap2D_mirrorX								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.4.29			Status : working   			*/
/*																						*/
/****************************************************************************************/

void Bitmap2D_mirrorX(uint16_t * addres,Dimension2D_t *size)
{
	uint16_t yCounter;
	uint16_t counterX;
	uint16_t tmpValue;
	uint16_t *position;
	uint16_t *mirrorPosition;


	for (yCounter=0;yCounter<size->y;yCounter++)
		{
		position=addres+(size->x*yCounter);

		mirrorPosition=position+(size->x-1);

		for (counterX=0;counterX<(size->x>>1)-1;counterX++)
		{
		tmpValue=*position;
		*position++=*mirrorPosition;
		*mirrorPosition--=tmpValue;
		}
		}




}


/****************************************************************************************/
/*																						*/
/*	Function : Bitmap2D_mirrorY								Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.4.29			Status : working   			*/
/*																						*/
/****************************************************************************************/

void Bitmap2D_mirrorY(uint16_t * addres,Dimension2D_t *size)
{
	uint8_t counterX;
	uint8_t counterY;
	uint16_t tmpValue;
	uint16_t *position;
	uint16_t *mirrorPosition;


	for (counterY=0;counterY<(size->y>>1);counterY++)
			{
			position=addres+(counterY*size->x);
			mirrorPosition=addres+(size->x*(size->y-1-counterY));

			for (counterX=0;counterX<size->x;counterX++)
				{
				tmpValue=*position;
				*position++=*mirrorPosition;
				*mirrorPosition++=tmpValue;
				}
			}


}


/****************************************************************************************/
/*																						*/
/*	Function : Bitmap2D_not									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.4.30			Status : working   			*/
/*																						*/
/****************************************************************************************/

void Bitmap2D_not(uint16_t * addres, uint16_t size)
{
	uint16_t  counter;

	for (counter=0;counter<size;counter++)
		{
		*addres=!*addres;
		addres++;
		}
}

/****************************************************************************************/
/*																						*/
/*	Function : Bitmap2D_min									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.4.30			Status : working   			*/
/*																						*/
/****************************************************************************************/


void Bitmap2D_min(uint16_t * destinationAddres,uint16_t * connectivAddres, Dimension2D_t * destinationSize, Dimension2D_t * connectivSize)
{
	uint16_t redD;
	uint16_t greenD;
	uint16_t blueD;

	uint16_t redS;
	uint16_t greenS;
	uint16_t blueS;

	uint16_t xCounter;
	uint16_t yCounter;

	uint16_t xConnectiv;
	uint16_t yConnectiv;


	uint16_t *sourceAddres;


	yConnectiv=0;


	for (yCounter=0;yCounter<destinationSize->y;yCounter++)
		{
		xConnectiv=0;

		sourceAddres=connectivAddres+(yConnectiv*connectivSize->x);

		for (xCounter=0;xCounter<destinationSize->x;xCounter++)
			{
			redD=*destinationAddres & 0xf;
			greenD=*destinationAddres & 0xf0;
			blueD=*destinationAddres & 0xf00;

			redS=*sourceAddres & 0xf;
			greenS=*sourceAddres & 0xf0;
			blueS=*sourceAddres & 0xf00;



			if (redS<redD)
				{
				 redD=redS;
				}

			if (greenS<greenD)
				{
				greenD=greenS;
				}

			if (blueS<blueD)
				{
				blueD=blueS;
				}


			*destinationAddres++=( redD | greenD | blueD );
			sourceAddres++;
			xConnectiv++;

			if (xConnectiv>=connectivSize->x)
				{
				xConnectiv=0;
				sourceAddres=connectivAddres+(yConnectiv*connectivSize->x);
				}

			}

		yConnectiv++;
		if (yConnectiv>=connectivSize->y)
			yConnectiv=0;

	}

}


/****************************************************************************************/
/*																						*/
/*	Function : Bitmap2D_max									Author : OG					*/
/*																						*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.4.30			Status : working   			*/
/*																						*/
/****************************************************************************************/

void Bitmap2D_max(uint16_t * destinationAddres,uint16_t * connectivAddres, Dimension2D_t * destinationSize, Dimension2D_t * connectivSize)
{
	uint16_t redD;
	uint16_t greenD;
	uint16_t blueD;

	uint16_t redS;
	uint16_t greenS;
	uint16_t blueS;

	uint16_t xCounter;
	uint16_t yCounter;

	uint16_t xConnectiv;
	uint16_t yConnectiv;


	uint16_t *sourceAddres;


	yConnectiv=0;


	for (yCounter=0;yCounter<destinationSize->y;yCounter++)
		{
		xConnectiv=0;

		sourceAddres=connectivAddres+(yConnectiv*connectivSize->x);

		for (xCounter=0;xCounter<destinationSize->x;xCounter++)
			{
			redD=*destinationAddres & 0xf;
			greenD=*destinationAddres & 0xf0;
			blueD=*destinationAddres & 0xf00;

			redS=*sourceAddres & 0xf;
			greenS=*sourceAddres & 0xf0;
			blueS=*sourceAddres & 0xf00;



			if (redS>redD)
				{
				 redD=redS;
				}

			if (greenS>greenD)
				{
				greenD=greenS;
				}

			if (blueS>blueD)
				{
				blueD=blueS;
				}


			*destinationAddres++=( redD | greenD | blueD );
			sourceAddres++;
			xConnectiv++;

			if (xConnectiv>=connectivSize->x)
				{
				xConnectiv=0;
				sourceAddres=connectivAddres+(yConnectiv*connectivSize->x);
				}

			}

		yConnectiv++;
		if (yConnectiv>=connectivSize->y)
			yConnectiv=0;

	}

}


/****************************************************************************************/
/*																						*/
/*	Function : Display2D_print5x5Char									Author :  OG 	*/
/*																	  					*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.3.26			Status : Working   			*/
/*																						*/
/****************************************************************************************/


boolean Bitmap2D_print5x5Char(uint16_t * addres, Dimension2D_t *origin,Dimension2D_t *bitmapSize,uint8_t index,uint16_t color)

{
	uint8_t characterLine;
	int8_t lineCounter;
	int8_t columnCounter;
	Pixel2D_t pixel;

	if ((index<32) || (index>128) )
		return(FALSE);



	index-=32;


	if ((origin->x<-4) || (origin->x>bitmapSize->x) ||
			(origin->y<-4) || (origin->y>bitmapSize->y))
		 return(FALSE);


	pixel.displaySize.x=bitmapSize->x;
	pixel.displaySize.y=bitmapSize->y;

	for (lineCounter=0;lineCounter<5;lineCounter++)
		{
		characterLine=Font_5x5[index] [4-lineCounter];

		for (columnCounter=4;columnCounter>=0;columnCounter--)
			{
			if ((characterLine & 0x1)>0)
				{
				pixel.position.x=origin->x+ columnCounter;
				pixel.position.y=origin->y+ lineCounter;
				Bitmap2D_setPixel(pixel, addres,color);
				}
				characterLine>>=1;
			}

		}



	return(true);
}

/****************************************************************************************/
/*																						*/
/*	Function : Bitmap2D_print8x8Char									Author :  OG 	*/
/*																	  					*/
/*	Description : 								   										*/
/*																						*/
/*	Version : 1.0					Date :2011.3.26			Status : Working   			*/
/*																						*/
/****************************************************************************************/

boolean Bitmap2D_print8x8Char(uint16_t * addres, Dimension2D_t *origin,Dimension2D_t *bitmapSize,uint8_t index,uint16_t color)
{
	uint8_t characterLine;
	int8_t lineCounter;
	int8_t columnCounter;
	Pixel2D_t pixel;

	if ((index<32) || (index>128) )
		return(FALSE);



	index-=32;


	if ((origin->x<-7) || (origin->x>bitmapSize->x) ||
			(origin->y<-7) || (origin->y>bitmapSize->y))
		 return(FALSE);


	pixel.displaySize.x=bitmapSize->x;
	pixel.displaySize.y=bitmapSize->y;

	for (lineCounter=0;lineCounter<8;lineCounter++)
		{
		characterLine=Font_8x8[index] [7-lineCounter]; // TODO mirror Font to avoid subtraction

		for (columnCounter=7;columnCounter>=0;columnCounter--)
			{
			if ((characterLine & 0x1)>0)
				{
				pixel.position.x=origin->x+ columnCounter;
				pixel.position.y=origin->y+ lineCounter;
				Bitmap2D_setPixel(pixel, addres,color);
				}
				characterLine>>=1;
			}

		}



	return(true);
}
